#include "common/pch.h"

#include "app/app.h"
#include "listener/gglistener.h"
#include "metadata/metamgr.h"
#include <cftc/reflect/object.h>
#include <cftc/reflect/class.h>
#include <cftc/reflect/type.h>
#include <cftc/util/strutils.h>
#include <cftc/typecontainer/list.h>
#include <cftc/util/listentry.h>
#include <cftc/reflect/field.h>
#include <cftf/net/msghandler.h>
#include <cftf/mysql/dbpool.h>
#include <cftf/loger/syslog.h>

#include "cs/cs_message.h"
#include "cs/msg_descriptor.h"
#include "msghandler/msghandler.h"
#include "listener/ggsession.h"
#include "dbc/dbcfmt.h"
#include "dbc/structure.h"
#include "dbc/dbcmgr.h"
#include "map/mapmgr.h"
#include "world/world.h"
#include "metadata/sql_template.h"
#include "metadata/creatureinfo.h"
#include "player/playermgr.h"

App::App()
{    
}

const std::string App::GetPkgName()
{
    return "mangosd";
}

int App::GetPreprocessThreadNum()
{
    return 1;
}

void App::Init()
{
    RegisterConstant();
    cftf::loger::SysLog::Instance().Info("hello");
    dbc::DbcMgr::Instance().Init();
    mt::MetaMgr::Instance().Init();
    World::Instance().Init();   
    GGListener::Instance().Init();
    MsgHandler::Instance().Init();
}

void App::UnInit()
{
    MsgHandler::Instance().UnInit();
    GGListener::Instance().UnInit();
    World::Instance().UnInit();
    mt::MetaMgr::Instance().UnInit();
    dbc::DbcMgr::Instance().UnInit();
}

void App::Update(unsigned int diff)
{   

}

bool App::HasTask()
{
    return false;
}

void App::DispatchSocketMsg(cftf::net::MsgHdr* hdr)
{
    switch ((SocketFrom_e)hdr->GetSocketFrom())
    {
    case SocketFrom_e::kSkGG:
    {
        DispatchGGMsg(hdr);
        break;
    }
    default:
        break;
    }
}

void App::PreprocessSocketMsg(cftf::net::MsgHdr* hdr)
{
    if (hdr->GetEvent() == cftf::SocketEvent_e::kSeRead) {
        MsgHandler::Instance().GetCsHandler().Parse(hdr);
    }
}

void App::RegisterConstant()
{
    cftc::reflect::Type::RegisterConstant("MAX_ITEM_PROTO_DAMAGES", MAX_ITEM_PROTO_DAMAGES);
    cftc::reflect::Type::RegisterConstant("MAX_ITEM_PROTO_SPELLS", MAX_ITEM_PROTO_SPELLS);
    cftc::reflect::Type::RegisterConstant("MAX_ITEM_PROTO_STATS", MAX_ITEM_PROTO_STATS);
    cftc::reflect::Type::RegisterConstant("MAX_TALENT_RANK", MAX_TALENT_RANK);

    cftc::reflect::Type::RegisterConstant("mt.sql_template.CreatureData_Loader", mt::sql_template::CreatureData_Loader);
    cftc::reflect::Type::RegisterConstant("mt.sql_template.GameObjectData_Loader", mt::sql_template::GameObjectData_Loader);
    cftc::reflect::Type::RegisterConstant("mt.sql_template.PoolCreatureTemplate_Loader", mt::sql_template::PoolCreatureTemplate_Loader);
    cftc::reflect::Type::RegisterConstant("mt.sql_template.PoolGameObjectTemplate_Loader", mt::sql_template::PoolGameObjectTemplate_Loader);

    cftc::reflect::Type::RegisterConstant("mt.CreatureInfo.MAX_KILL_CREDIT", mt::CreatureInfo::MAX_KILL_CREDIT);
    cftc::reflect::Type::RegisterConstant("mt.CreatureInfo.MAX_CREATURE_MODEL", mt::CreatureInfo::MAX_CREATURE_MODEL);
    cftc::reflect::Type::RegisterConstant("mt.CreatureInfo.USE_DEFAULT_DATABASE_LEVEL", mt::CreatureInfo::USE_DEFAULT_DATABASE_LEVEL);

    cftc::reflect::Type::RegisterConstant("dbc.fmt.AreaTableEntryfmt", dbc::fmt::AreaTableEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.AreaTriggerEntryfmt", dbc::fmt::AreaTriggerEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.AuctionHouseEntryfmt", dbc::fmt::AuctionHouseEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.BankBagSlotPricesEntryfmt", dbc::fmt::BankBagSlotPricesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ChrClassesEntryfmt", dbc::fmt::ChrClassesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ChrRacesEntryfmt", dbc::fmt::ChrRacesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CharStartOutfitEntryfmt", dbc::fmt::CharStartOutfitEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ChatChannelsEntryfmt", dbc::fmt::ChatChannelsEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CinematicSequencesEntryfmt", dbc::fmt::CinematicSequencesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CreatureDisplayInfofmt", dbc::fmt::CreatureDisplayInfofmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CreatureDisplayInfoExtrafmt", dbc::fmt::CreatureDisplayInfoExtrafmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CreatureFamilyfmt", dbc::fmt::CreatureFamilyfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CreatureSpellDatafmt", dbc::fmt::CreatureSpellDatafmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.CreatureTypefmt", dbc::fmt::CreatureTypefmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.DurabilityCostsfmt", dbc::fmt::DurabilityCostsfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.DurabilityQualityfmt", dbc::fmt::DurabilityQualityfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.EmotesEntryfmt", dbc::fmt::EmotesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.EmotesTextEntryfmt", dbc::fmt::EmotesTextEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.FactionEntryfmt", dbc::fmt::FactionEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.FactionTemplateEntryfmt", dbc::fmt::FactionTemplateEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.GameObjectDisplayInfofmt", dbc::fmt::GameObjectDisplayInfofmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ItemBagFamilyfmt", dbc::fmt::ItemBagFamilyfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ItemClassfmt", dbc::fmt::ItemClassfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ItemRandomPropertiesfmt", dbc::fmt::ItemRandomPropertiesfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.ItemSetEntryfmt", dbc::fmt::ItemSetEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.LiquidTypefmt", dbc::fmt::LiquidTypefmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.LockEntryfmt", dbc::fmt::LockEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.MailTemplateEntryfmt", dbc::fmt::MailTemplateEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.MapEntryfmt", dbc::fmt::MapEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.MovieEntryfmt", dbc::fmt::MovieEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.QuestSortEntryfmt", dbc::fmt::QuestSortEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SkillLinefmt", dbc::fmt::SkillLinefmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SkillLineAbilityfmt", dbc::fmt::SkillLineAbilityfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SkillRaceClassInfofmt", dbc::fmt::SkillRaceClassInfofmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SoundEntriesfmt", dbc::fmt::SoundEntriesfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellCastTimefmt", dbc::fmt::SpellCastTimefmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellDurationfmt", dbc::fmt::SpellDurationfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellEntryfmt", dbc::fmt::SpellEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellFocusObjectfmt", dbc::fmt::SpellFocusObjectfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellItemEnchantmentfmt", dbc::fmt::SpellItemEnchantmentfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellRadiusfmt", dbc::fmt::SpellRadiusfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellRangefmt", dbc::fmt::SpellRangefmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.SpellShapeshiftfmt", dbc::fmt::SpellShapeshiftfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.StableSlotPricesfmt", dbc::fmt::StableSlotPricesfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.TalentEntryfmt", dbc::fmt::TalentEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.TalentTabEntryfmt", dbc::fmt::TalentTabEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.TaxiNodesEntryfmt", dbc::fmt::TaxiNodesEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.TaxiPathEntryfmt", dbc::fmt::TaxiPathEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.TaxiPathNodeEntryfmt", dbc::fmt::TaxiPathNodeEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.WMOAreaTableEntryfmt", dbc::fmt::WMOAreaTableEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.WorldMapAreaEntryfmt", dbc::fmt::WorldMapAreaEntryfmt);
    cftc::reflect::Type::RegisterConstant("dbc.fmt.WorldSafeLocsEntryfmt", dbc::fmt::WorldSafeLocsEntryfmt);

    cftc::reflect::Type::RegisterConstant("dbc.MapEntry.NAME_SIZE", dbc::MapEntry::NAME_SIZE);

    cftc::reflect::Type::RegisterConstant("MAX_SPELL_TOTEMS", MAX_SPELL_TOTEMS);
    cftc::reflect::Type::RegisterConstant("MAX_SPELL_REAGENTS", MAX_SPELL_REAGENTS);
    cftc::reflect::Type::RegisterConstant("MAX_EFFECT_INDEX", MAX_EFFECT_INDEX);
}

void App::DispatchGGMsg(cftf::net::MsgHdr* hdr)
{
    switch (hdr->GetEvent())
    {
    case cftf::SocketEvent_e::kSeConnected:
    {
        auto msg = std::make_shared<cs::SMAuthChallenge>();
        if (GGListener::Instance().TouchSession((int)hdr->GetSocketHandle(),
            [msg](GGSession* sesssion)
            {
                msg->seed = sesssion->GetSpeed();
            })) {
            GGListener::Instance().SendMsg((int)hdr->GetSocketHandle(), msg);
        }
        break;
    }
    case cftf::SocketEvent_e::kSeDisConnect:
    {
        player::PlayerMgr::Instance().OnSocketDiscount((int)hdr->GetSocketHandle());
        break;
    }
    case cftf::SocketEvent_e::kSeRead:
    {
        MsgHandler::Instance().ProcMsg(hdr);
        break;
    }
    default:
    {
        break;
    }
    }
}